package com.feituan.core.util;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 日期处理工具类
 */
public class DateUtils {
	public static final String SHUABAO_DATE = "yyyy-MM-dd hh:mm";
	public static final String SHORT_DATE_FORMAT_STR = "yyyy-MM-dd";
	public static final String MONTH_DATE_SHORT_FORMAT_STR = "yyyyMM";
	public static final String MONTH_DATE_LONG_FORMAT_STR = "yyyy-MM";
	public static final String LONG_DATE_FORMAT_STR = "yyyy-MM-dd HH:mm:ss";
	public static final String MAX_LONG_DATE_FORMAT_STR = "yyyy-MM-dd HH:mm:ss SSS";
	public static final String EARLY_TIME = "00:00:00 000";
	public static final String LATE_TIME = "23:59:59";
	public static final String EARER_IN_THE_DAY = "yyyy-MM-dd 00:00:00 000";
	public static final String LATE_IN_THE_DAY = "yyyy-MM-dd 23:59:59 999";
	public static final long DAY_LONG = 24 * 60 * 60 * 1000;
	public static final String YYYY_MM_DD = "yyyy-MM-dd";
	public static final String yyyyMMdd ="yyyyMMdd";
	public static final String MAX_DATETIME = "9999-12-31 23:59:59";
	public static final Long MAX_DATETIME_SECONDS = 253402271999l;
	public static final Date FIRST_DAY_OF_YEAR_1970 = DateUtils.parse("1970-01-01 00:00:00", LONG_DATE_FORMAT_STR);
	public static final Date FIRST_DAY_OF_YEAR_2100 = DateUtils.parse("2100-01-01 00:00:00", LONG_DATE_FORMAT_STR);

	/**
	 * 得到某个日期在这一天中时间最早的日期对象
	 * 
	 * @param date
	 * @return
	 * @throws ParseException
	 */
	public static Date getEarlyInTheDay(Date date) throws ParseException {
		String dateString = new SimpleDateFormat(SHORT_DATE_FORMAT_STR).format(date) + " " + EARLY_TIME;
		return new SimpleDateFormat(LONG_DATE_FORMAT_STR).parse(dateString);
	}

	public static Date getMaxDateTime(){
		return new Date(MAX_DATETIME_SECONDS * 1000);
	}
	
	/**
	 * 得到某天最早的时间
	 * @param date
	 * @return
	 */
	public static Date getFirstOfDay(Date date) {
		String dateString = new SimpleDateFormat(EARER_IN_THE_DAY).format(date);
		try {
			return new SimpleDateFormat(LONG_DATE_FORMAT_STR).parse(dateString);
		} catch (ParseException e) {
			return null;
		}
	}

	/**
	 * 得到某个日期在这一天中时间最晚的日期对象
	 * 
	 * @param date
	 * @return
	 * @throws ParseException
	 */
	public static Date getLateInTheDay(Date date) throws ParseException {
		String dateString = new SimpleDateFormat(SHORT_DATE_FORMAT_STR).format(date) + " " + LATE_TIME;
		return new SimpleDateFormat(LONG_DATE_FORMAT_STR).parse(dateString);
	}

	/**
	 * 增加时间的秒数
	 * 
	 * @param date 要增加的日期
	 * @param second 增加的时间（以秒为单位）
	 * @return 增加时间后的日期
	 */

	public static Date addSecond(Date date, int second) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		cal.add(Calendar.SECOND, second);
		return cal.getTime();
	}



	/**
	 * 根据传入日期计算和当前日期的相差天数
	 * 
	 * @param date
	 * @return
	 */
	public static long subtractNowDay(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		long dateTimeInMillis = calendar.getTimeInMillis();
		Calendar nowCalendar = Calendar.getInstance();
		nowCalendar.setTime(new Date());
		long nowTimeInMillis = nowCalendar.getTimeInMillis();
		return (nowTimeInMillis - dateTimeInMillis) / (24 * 60 * 60 * 1000);
	}

	/**
	 * 获取结束日期与开始日期相差的秒数
	 * 
	 * @param startDate 开始日期
	 * @param endDate 结束日期
	 * @return
	 */
	public static long subtractSecond(Date startDate, Date endDate) {
		Calendar startCalendar = Calendar.getInstance();
		startCalendar.setTime(startDate);
		long startTimeInMillis = startCalendar.getTimeInMillis();
		Calendar endCalendar = Calendar.getInstance();
		endCalendar.setTime(endDate);
		long endTimeInMillis = endCalendar.getTimeInMillis();
		return (endTimeInMillis - startTimeInMillis) / 1000;

	}

	/**
	 * 字符串按自定格式更新
	 * 
	 * @param dateString
	 * @param format
	 * @return
	 * @throws ParseException
	 */
	public static Date parserStringToDate(String dateString, String format) throws ParseException {
		DateFormat dateFormat = new SimpleDateFormat(format);
		return dateFormat.parse(dateString);
	}
	
	public static Date parse(String dateString, String format){
		Date date = null;
		try{
			date = parserStringToDate(dateString, format);
		}catch(Exception e){}
		return date;
	}

	/**
	 * 日期加减
	 * 
	 * @param date
	 * @param dateInterval
	 * @return
	 */
	public static Date dateInterval(Date date, int dateInterval) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		cal.add(Calendar.DAY_OF_MONTH, dateInterval);
		return cal.getTime();
	}
	

	public static Date getBeginOfDay(Date date) {
		String beginDay = new SimpleDateFormat(EARER_IN_THE_DAY).format(date);
		try {
			return parserStringToDate(beginDay, LONG_DATE_FORMAT_STR);
		} catch (ParseException e) {
		}
		return null;
	}

	public static Date getEndOfDay(Date date) {
		String endDay = new SimpleDateFormat(LATE_IN_THE_DAY).format(date);
		try {
			return parserStringToDate(endDay, MAX_LONG_DATE_FORMAT_STR);
		} catch (ParseException e) {
		}
		return null;
	}

	public static String formatDate(Date date, String format) {
		DateFormat dateFormat = new SimpleDateFormat(format);
		return dateFormat.format(date);
	}

	public static Calendar getCalendar(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		return calendar;
	}

	public static long truncateDate(Date beginDate, Date endDate) {
		if (endDate != null && beginDate != null) {
			GregorianCalendar end = new GregorianCalendar();
			end.setTime(endDate);

			GregorianCalendar begin = new GregorianCalendar();
			begin.setTime(beginDate);

			return (end.getTimeInMillis() - begin.getTimeInMillis()) / DAY_LONG;
		}
		return 0;
	}

	public static Date add(Date date, int field, int value) {
		Calendar calendar = calendar(date);
		calendar.add(field, value);
		return calendar.getTime();
	}

	public static Calendar calendar(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		return calendar;
	}

	public static Date getDateWithoutTime(Date date) {
		String dateString = new SimpleDateFormat(SHORT_DATE_FORMAT_STR).format(date);
		try {
			return new SimpleDateFormat(SHORT_DATE_FORMAT_STR).parse(dateString);
		} catch (ParseException e) {
			return null;
		}
	}

	/**
	 * 获取最近30天的开始时间(最近30天包含调用该方法的当天)
	 * @return 开始时间
	 */
	public static Date getStartTimeOfLast30Days(){
		Calendar calendar  = calendar(new Date());
		calendar.add(Calendar.DAY_OF_MONTH, -29);
		calendar.set(Calendar.HOUR_OF_DAY,0);
		calendar.set(Calendar.MINUTE,0);
		calendar.set(Calendar.SECOND, 0);
		return calendar.getTime();
	}
	public static int getDayOfWeek(Date date){
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		return calendar.get(Calendar.DAY_OF_WEEK);
	}

	public static Date format(Date date, String format) throws Exception {
		String dateStr = formatDate(date, format);
		return parserStringToDate(dateStr, format);
	}

	/**
	 * 获取当前月的第n天的零点零分零秒
	 *
	 * @param nth 第n天
	 * @return
	 */
	public static  Date getDateTimeOfCurrentMonthNthDay(int nth){
		Calendar calendar = Calendar.getInstance();
		calendar.set(Calendar.DAY_OF_MONTH, nth);
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		return calendar.getTime();
	}

	public static  String getBeginDayBeginTimeOfMonth(int year, int month){
		Calendar calendar = Calendar.getInstance();
		calendar.set(Calendar.YEAR, year);
		calendar.set(Calendar.MONTH, month - 1);
		calendar.set(Calendar.DAY_OF_MONTH, 1);
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		return formatDate(calendar.getTime(), LONG_DATE_FORMAT_STR);
	}

	public static  String getEndDayEndTimeOfMonth(int year, int month){
		Calendar calendar = Calendar.getInstance();
		calendar.set(Calendar.YEAR, year);
		calendar.set(Calendar.MONTH, month);
		calendar.set(Calendar.DAY_OF_MONTH, 1);
		calendar.add(Calendar.DAY_OF_MONTH, -1);
		calendar.set(Calendar.HOUR_OF_DAY, 23);
		calendar.set(Calendar.MINUTE, 59);
		calendar.set(Calendar.SECOND, 59);
		return formatDate(calendar.getTime(), LONG_DATE_FORMAT_STR);
	}

	public static void main(String[] args) throws Exception {
		Date date1 = parserStringToDate("2014-07-02", SHORT_DATE_FORMAT_STR);
		Date date2 = parserStringToDate("2014-07-01", SHORT_DATE_FORMAT_STR);
		System.out.println(truncateDate(date1, date2));
		
		System.out.println(formatDate(getFirstOfDay(new Date()), "yyyy-MM-dd HH:mm:ss SSS"));
		System.out.println(formatDate(getEndOfDay(new Date()),"yyyy-MM-dd HH:mm:ss SSS"));
		System.out.println(formatDate(getStartTimeOfLast30Days(),LONG_DATE_FORMAT_STR));


		//获取最近一个月开始的时间戳
		Date startTimeOfLast30Days = DateUtils.getStartTimeOfLast30Days();
		long startTimeStamp = startTimeOfLast30Days.getTime() / 1000;

		List<Long> startTimeStampOfEveryDayList = new ArrayList<>();
		//最近30天每天的开始时间戳
		for(int i = 0; i < 30; i++){
			startTimeStampOfEveryDayList.add(startTimeStamp + i * 86400);
		}

		for(Long ss : startTimeStampOfEveryDayList){
			System.out.println(ss);
		}
		Collections.shuffle(startTimeStampOfEveryDayList);
		for(Long ss : startTimeStampOfEveryDayList){
			System.out.println(formatDate(new Date(ss * 1000),LONG_DATE_FORMAT_STR));
		}

	}
}
